package cn.nfwx.tv.util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

import android.app.AppOpsManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Build;
import android.support.v4.app.NotificationCompat;
import android.text.TextUtils;

import cn.nfwx.tv.R;

public class NotificationUtils {

    static final String DEFAULT_BROWSER = "android.intent.category.DEFAULT";
    static final String BROWSABLE = "android.intent.category.BROWSABLE";
    static final String VIEW_ACTION = "android.intent.action.VIEW";

    static final int NOTIFICATION_ID = 1000;

    public static void showNotificationMessage(Context context, String message) {
        showNotification(context, "", message, false, null);
    }

    public static void showNotificationMessage(Context context, String title,
                                               String message) {
        showNotification(context, title, message, false, null);
    }

    public static void showNotificationMessage(Context context, String title,
                                               String message, Intent intent) {
        showNotification(context, title, message, true, intent);
    }

    public static void showNotificationMessage(Context context, String title,
                                               String message, String url) {
        Intent intent = getBrowserIntent(context, url);

        showNotification(context, title, message, true, intent);
    }

    private static void showNotification(Context context, String title,
                                         String message, boolean autoCancel, Intent intent) {
        if (TextUtils.isEmpty(title)) {
            title = context.getResources().getString(R.string.app_name);
        }

        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
                context);
        mBuilder.setContentTitle(title).setContentText(message)
                .setTicker(message).setWhen(System.currentTimeMillis())
                .setAutoCancel(autoCancel).setOngoing(false)
                .setDefaults(Notification.DEFAULT_SOUND)
                .setSmallIcon(getIcon(context));

        if (intent != null) {
            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
                    intent, PendingIntent.FLAG_CANCEL_CURRENT);
            mBuilder.setContentIntent(pendingIntent);
        }

        NotificationManager notificationManager = (NotificationManager) context
                .getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(NOTIFICATION_ID, mBuilder.build());
    }

    private static Intent getBrowserIntent(Context context, String url) {
        ActivityInfo actionInfo = getBrowserApp(context);
        if (actionInfo == null) {
            return null;
        }

        Intent intent = new Intent(VIEW_ACTION);
        intent.setData(Uri.parse(url));
        intent.setClassName(actionInfo.packageName, actionInfo.name);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        return intent;
    }

    // 找出手机当前安装的所有浏览器程序
    private static ActivityInfo getBrowserApp(Context context) {
        Intent intent = new Intent(VIEW_ACTION);
        intent.addCategory(DEFAULT_BROWSER);
        intent.addCategory(BROWSABLE);
        intent.setDataAndType(Uri.parse("http://"), null);

        List<ResolveInfo> resolveInfoList = context.getPackageManager()
                .queryIntentActivities(intent,
                        PackageManager.GET_INTENT_FILTERS);
        if (resolveInfoList.isEmpty()) {
            return null;
        }

        return resolveInfoList.get(0).activityInfo;
    }

    private static final String CHECK_OP_NO_THROW = "checkOpNoThrow";
    private static final String OP_POST_NOTIFICATION = "OP_POST_NOTIFICATION";

    public static boolean isNotificationEnabled(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            AppOpsManager mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);

            ApplicationInfo appInfo = context.getApplicationInfo();
            String pkg = context.getApplicationContext().getPackageName();
            int uid = appInfo.uid;

            Class appOpsClass = null;
            try {
                appOpsClass = Class.forName(AppOpsManager.class.getName());
                Method checkOpNoThrowMethod = appOpsClass.getMethod(CHECK_OP_NO_THROW, Integer.TYPE, Integer.TYPE,
                        String.class);
                Field opPostNotificationValue = appOpsClass.getDeclaredField(OP_POST_NOTIFICATION);

                int value = (Integer) opPostNotificationValue.get(Integer.class);
                return ((Integer) checkOpNoThrowMethod.invoke(mAppOps, value, uid, pkg) == AppOpsManager.MODE_ALLOWED);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e ) {
                e.printStackTrace();
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            return false;
        }
        return true;
    }

    private static int getIcon(Context context) {

        final PackageManager packageManager = context.getPackageManager();
        ApplicationInfo appInfo = null;
        try {
            appInfo = packageManager.getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        if (appInfo != null) {
            return appInfo.icon;
        }
        return 0;
    }
}
